package com.aispeech.detector;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.Toast;

import com.aispeech.detector.utils.AudioFileWrite;
import com.aispeech.detector.utils.DataUtils;
import com.aispeech.detector.utils.SamplePlayer;
import com.aispeech.detector.view.voiceView.MicAmplitudeView;
import com.aispeech.rcprvd.RcPrvdListener;
import com.aispeech.rcprvd.RemoteRecord;
import com.aispeech.rcprvd.utils.RcPrvdConst;

import java.io.File;

public class RemoteRecActivity extends AppCompatActivity implements View.OnClickListener {
    private final String TAG = "RemoteRecActivity";
    private Spinner mSpinnerSupportRcDev;
    private Button mBtnRecord, mBtnPlay;
    private MicAmplitudeView mMicAmpView;
    private ImageView mIvThumbClick;

    private RemoteRecord mRemoteRecord;
    private int mCurrentSelectDeviceFlag = 0;

    private boolean isRecording = false;
    private boolean isPlaying = false;
    private boolean isKeyDown = false;
    private int[] mPositionMap = {
            RcPrvdConst.RCDevSource.NANO_HID,
            RcPrvdConst.RCDevSource.NANO_BLE_NODE,
            RcPrvdConst.RCDevSource.JINJU_BLE_GATT,
            RcPrvdConst.RCDevSource.BLE_AUDIO
    };

    private AudioFileWrite mAudioFile;
    private String AudioFilePath;
    private SamplePlayer mPlayer;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_remote_rec);
        initView();
        initRemoteRecord(mPositionMap[mCurrentSelectDeviceFlag]);

        mAudioFile = new AudioFileWrite(getApplication());
        mPlayer = new SamplePlayer(new SamplePlayer.SamplePlayerStateListener() {
            @Override
            public void onStart() {
                updatePlayerSate(true);
            }

            @Override
            public void onStop() {
                updatePlayerSate(false);
            }

            @Override
            public void onError(String err) {
                Toast.makeText(getBaseContext(), getResources().getString(R.string.play_operation_failed) + err, Toast.LENGTH_LONG).show();
            }
        });
        AudioFilePath = getBaseContext().getExternalCacheDir() + File.separator + "rec.pcm";
    }

    private void updatePlayerSate(final boolean state) {
        Log.d(TAG, "updatePlayerSate() called with: isPlaying = [" + state + "]");
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                isPlaying = state;
                if (isPlaying) {
                    mBtnPlay.setText(getResources().getString(R.string.btn_play_stop));
                } else {
                    mBtnPlay.setText(getResources().getString(R.string.btn_play_start));
                }
            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        releaseRemoteRecord();
        if (null != mPlayer && mPlayer.isPlaying()) {
            mPlayer.trackStop();
        }
        if (null != mAudioFile) {
            mAudioFile.closeWrite();
        }
    }

    private void initRemoteRecord(int source) {
        mRemoteRecord = RemoteRecord.getInstance();
        String libVersion = mRemoteRecord.getLibVersion();
        Log.d(TAG, "initRemoteRecord: libVersion = " + libVersion);
        Log.d(TAG, "initRemoteRecord: mCurrentSelectDeviceSource = " + mCurrentSelectDeviceFlag);
        mRemoteRecord.init(source, getApplication(), mRcPrvdListener);
    }

    private void releaseRemoteRecord() {
        Log.d(TAG, "releaseRemoteRecord: ");
        if (null != mRemoteRecord) {
            mRemoteRecord.release();
        }
    }

    private void initView() {
        mSpinnerSupportRcDev = findViewById(R.id.sp_support_dev_list);
        mSpinnerSupportRcDev.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                Log.d(TAG, "onItemSelected() position = [" + position + "], id = [" + id + "]");
                if (position != mCurrentSelectDeviceFlag) {
                    mCurrentSelectDeviceFlag = position;
                    releaseRemoteRecord();
                    initRemoteRecord(mPositionMap[mCurrentSelectDeviceFlag]);
                }
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {
                Log.d(TAG, "onNothingSelected: ");
            }
        });

        mBtnRecord = findViewById(R.id.btn_remote_record);
        mBtnRecord.setOnClickListener(this);
        mBtnPlay = findViewById(R.id.btn_play_rec_file);
        mBtnPlay.setOnClickListener(this);

        mMicAmpView = findViewById(R.id.mav_remote_rec_amp_view);
        mMicAmpView.setChannels(1);

        mIvThumbClick = findViewById(R.id.iv_thumb_click);
    }


    @Override
    public void onClick(View v) {
        if (v == mBtnRecord) {
            int ret;

            if (isPlaying) {
                mPlayer.trackStop();
            }

            if (isRecording) {
                ret = mRemoteRecord.stop();
                mAudioFile.closeWrite();
            } else {
                mAudioFile.startWrite(AudioFilePath);
                ret = mRemoteRecord.start();
            }
            if (ret == RcPrvdConst.ErrorCode.NO_ERROR) {
                isRecording = !isRecording;
                mBtnRecord.setText(isRecording ? getResources().getString(R.string.btn_record_stop) : getResources().getString(R.string.btn_record_start));
                mMicAmpView.setAlive(isRecording);
            } else {
                Toast.makeText(getBaseContext(), getResources().getString(R.string.record_operation_failed) + ": " + ret, Toast.LENGTH_SHORT).show();
            }
        } else if (v == mBtnPlay) {
            if (isRecording) {
                mRemoteRecord.stop();
                mAudioFile.closeWrite();
                isRecording = false;
                mBtnRecord.setText(getResources().getString(R.string.btn_record_start));
                mMicAmpView.setAlive(false);
            }
            if (isPlaying) {
                mPlayer.trackStop();
            } else {
                mPlayer.trackPlay(0, AudioFilePath);
            }
        }
    }

    private RcPrvdListener mRcPrvdListener = new RcPrvdListener() {
        @Override
        public void onKeyEvent(int keyCode, final int state) {
            Log.d(TAG, "onKeyEvent() called with: keyCode = [" + keyCode + "], state = [" + state + "]");
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    if (state == 0) {
                        isKeyDown = false;
                        mIvThumbClick.setVisibility(View.INVISIBLE);
                    } else {
                        isKeyDown = true;
                        mIvThumbClick.setVisibility(View.VISIBLE);
                    }
                }
            });

        }

        @Override
        public void onBuffer(final byte[] audioData) {
            if (null != mAudioFile) {
                mAudioFile.writeBuffer(audioData);
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        mMicAmpView.setChannelsAmp(0, DataUtils.countAmplitude(audioData, audioData.length) << 4);
                    }
                });
            }
        }
    };
}
